home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Simulation / PDP-8 Simulator / Source Code / PDP8_Main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-13  |  8.3 KB  |  393 lines  |  [TEXT/KAHL]

  1. /*************************************************************************************
  2. *
  3. *        Generic Appshell- a system 7.0 compatible application shell
  4. *
  5. *        ©1992 Graham Cox. All Rights Reserved.
  6. *
  7. *        This shell can be used as a basis for any application in THINK C- just add
  8. *        procedures as required. To minimise the need to alter this main file, the
  9. *        code is split into two sections- the main loop section and the code dispatching
  10. *        section. The code dispatch will need modification for each application, but the
  11. *        main section shouldnt. This shell supports standard apple events, DA's and
  12. *        all the usual malarkey. In addition, one resizeable non-specific window is
  13. *        opened, and dialogs provided for the about box, and printing. Uses resources
  14. *        from file "Generic Appshell.rsrc" which must be available to run this shell. 
  15. *
  16. *        Modification History:
  17. *        10/2/92 created from scratch.    
  18. *
  19. *
  20. *
  21. *************************************************************************************/
  22. #include    "GestaltEqu.h"
  23. #include    "Traps.h"
  24. #include    "PDPGlobalEqu.p"
  25. #include    "AppleEvents.h"
  26.  
  27. #include "PDP8_Main.proto.h"
  28.  
  29. /* Global Variables. You should try to minimise the number of these by planning your
  30.     code appropriately. */
  31.     
  32. MenuHandle        AppMenus[NumMenus];            /* Handles to the menus */
  33. int                done = FALSE;                /* Flag, App quits when true. */
  34. int                AsmError = 0;                /* assembly error code */
  35.  
  36. pascal OSErr   OpenApplication(AppleEvent *theAEvt,AppleEvent *reply,long hRefCon);
  37. pascal OSErr   OpenDocuments(AppleEvent *theAEvt,AppleEvent *reply,long hRefCon);
  38. pascal OSErr   PrintDocuments(AppleEvent *theAEvt,AppleEvent *reply,long hRefCon);
  39. pascal OSErr   QuitApplication(AppleEvent *theAEvt,AppleEvent *reply,long hRefCon);
  40.  
  41.  
  42. /* fixed code follows- in theory, this should not require modification */
  43.  
  44.  
  45. pascal long ShowCriticalMem(Size cbNeeded)
  46. {
  47.     /* critical memory alert message */
  48.     int        aHit;
  49.     
  50.     aHit = xAlert(CriticalMemoryAlert,NIL);
  51.     return(NIL);
  52. }
  53.  
  54.  
  55. SysInitialize(void)
  56. {
  57.     /* required system initialisation */
  58.     
  59.     int        canUseGestalt,index;
  60.     long    gResponse;
  61.     OSErr    theErr;
  62.     
  63.     InitGraf(&thePort);                        /* mac toolbox init stuff */
  64.     InitFonts();
  65.     InitWindows();
  66.     InitMenus();
  67.     TEInit();
  68.     InitDialogs(NIL);
  69.     
  70.     SetWatchCursor();
  71.     FlushEvents(everyEvent,0);
  72.     
  73.     for (index = 0;index<8;index++)
  74.         MoreMasters();
  75.     SetGrowZone(&ShowCriticalMem);
  76.         
  77.     InitxAlert(TRUE);                        /* allows correct positioning of alerts */
  78.     
  79.     if (GestaltAvailable()) {
  80.         theErr = Gestalt(gestaltAppleEventsAttr,&gResponse);
  81.         if (theErr == noErr && (gResponse & 1)) {
  82.             /* OK- Apple events are available, so install the standard ones */
  83.             
  84.             theErr = AEInstallEventHandler(kCoreEventClass,kAEOpenApplication,
  85.                                             &OpenApplication,0,FALSE);
  86.             theErr = AEInstallEventHandler(kCoreEventClass,kAEOpenDocuments,
  87.                                             &OpenDocuments,0,FALSE);
  88.             theErr = AEInstallEventHandler(kCoreEventClass,kAEPrintDocuments,
  89.                                             &PrintDocuments,0,FALSE);
  90.             theErr = AEInstallEventHandler(kCoreEventClass,kAEQuitApplication,
  91.                                             &QuitApplication,0,FALSE);
  92.         }
  93.         else
  94.             OpenNewWindow();
  95.     }
  96.     else
  97.         OpenNewWindow();
  98.     
  99. }
  100.  
  101.  
  102. main(void)
  103. {
  104.     /* application entry point to main program */
  105.     
  106.     SysInitialize();                        /* init system */
  107.     AppInitialize();                        /* init app specific stuff */
  108.     
  109.     GetAndProcessEvents();                    /* run the program */
  110.         
  111.     CleanUp();                                /* tail-end good housekeeping */
  112.     ExitToShell();                            /* return from this process */
  113. }
  114.  
  115.  
  116. int    NumToolTraps(void)
  117. {
  118.     /* returns number of toolbox traps */
  119.     
  120.     if (NGetTrapAddress(_InitGraf,ToolTrap) == 
  121.         NGetTrapAddress(0xAA6E,ToolTrap))
  122.             return(0x0200);
  123.         else
  124.             return(0x0400);
  125. }
  126.  
  127. #define    trapMask    0x0800
  128.  
  129.  
  130. int    GetTrapType(int theTrap)
  131. {
  132.     /* returns type of the trap */
  133.     
  134.     if (BitAnd(theTrap,trapMask) > 0)
  135.         return(ToolTrap);
  136.     else
  137.         return(OSTrap);
  138. }
  139.     
  140.  
  141. short TrapAvailable(int theTrap)
  142. {
  143.     /* general function for testing trap availability */
  144.  
  145.     int        tType;
  146.     
  147.     tType = GetTrapType(theTrap);
  148.     if (tType == ToolTrap) {
  149.         theTrap &= 0x07FF;
  150.         if (theTrap >= NumToolTraps())
  151.             theTrap = _Unimplemented;
  152.     }
  153.     return(NGetTrapAddress(theTrap,tType) != NGetTrapAddress(_Unimplemented,ToolTrap));
  154. }
  155.         
  156.  
  157. short WNEAvailable(void) 
  158. {
  159.     /* returns true if WNE is available */
  160.     
  161.     return(TrapAvailable(_WaitNextEvent));
  162. }
  163.  
  164.  
  165. short GestaltAvailable(void) 
  166. {
  167.     /* returns true if Gestalt is available */
  168.     
  169.     return(TrapAvailable(_GestaltDispatch));
  170. }
  171.  
  172.  
  173. GetAndProcessEvents(void)
  174. {
  175.     /* main event fetch loop. Uses WNE if possible, else GNE */
  176.     
  177.     EventRecord        theEvent;
  178.     OSErr            theErr;
  179.     short            UseWNE;
  180.     RgnHandle        CursRgn;
  181.     
  182.     CursRgn = NewRgn();
  183.     UseWNE = WNEAvailable();
  184.     
  185.     while (!done) {
  186.         
  187.         RunPDP(FrontWindow());
  188.         
  189.         if (UseWNE) {
  190.             AdjustCursor(theEvent.where,CursRgn);
  191.             if (WaitNextEvent(everyEvent,&theEvent,4,NIL))
  192.                 DoEvent(&theEvent);
  193.         }
  194.         else {
  195.             SystemTask();
  196.             AdjustCursor(theEvent.where,CursRgn);
  197.             if (GetNextEvent(everyEvent,&theEvent))
  198.                 DoEvent(&theEvent);
  199.         }
  200.     }
  201. }
  202.     
  203.     
  204. DoEvent(EventRecord* theEvent)
  205. {
  206.     /* dispatch raw events to process routines */
  207.     
  208.     switch (theEvent->what) {
  209.         case mouseDown:
  210.             ProcessClick(theEvent);
  211.             break;
  212.         case keyDown:
  213.             ProcessKey(theEvent);
  214.             break;
  215.         case autoKey:
  216.             ProcessAutoKey(theEvent);
  217.             break;
  218.         case activateEvt:
  219.             ProcessActivate(theEvent);
  220.             break;
  221.         case updateEvt:
  222.             ProcessUpdate(theEvent);
  223.             break;
  224.         case osEvt:
  225.             ProcessOSEvt(theEvent);
  226.             break;
  227.         case kHighLevelEvent:
  228.             ProcessHLE(theEvent);
  229.             break;
  230.         case  diskEvt:
  231.             {
  232.                 long    emCode;
  233.                 int        dmResult;
  234.                 Point    where;
  235.                 
  236.                 emCode = theEvent->message;
  237.                 if (HiWord(emCode) != noErr) {
  238.                     SetPt(&where,100,100);
  239.                     dmResult = DIBadMount(where,emCode);
  240.                 }    
  241.             }
  242.             break;
  243.         default:
  244.             break;
  245.     }
  246. }
  247.  
  248.  
  249. ProcessClick(EventRecord *theEvent){
  250.     /* dispatch mouse clicks */
  251.     
  252.     int            mClick,partCode;
  253.     WindowPtr    theWindow;
  254.     Point        mPoint;
  255.     long        mSelect;
  256.     
  257.     mPoint = theEvent->where;
  258.     mClick = FindWindow(mPoint,&theWindow);
  259.     switch (mClick) {
  260.         case inDesk:
  261.             break;
  262.         case inMenuBar:
  263.             MenuAdjust();
  264.             mSelect = MenuSelect(mPoint);
  265.             if (HiWord(mSelect) != 0) 
  266.                 DispatchMenu(mSelect);
  267.             HiliteMenu(0);
  268.             break;
  269.         case inSysWindow:
  270.             SystemClick(theEvent,theWindow);
  271.             break;
  272.         case inContent:
  273.             ClickTheWindow(theWindow,mPoint);
  274.             break;
  275.         case inDrag:
  276.             DragTheWindow(theWindow,mPoint);
  277.             break;
  278.         case inGrow:
  279.             GrowTheWindow(theWindow,mPoint);
  280.             break;
  281.         case inGoAway:
  282.             if (TrackGoAway(theWindow,mPoint))
  283.                 CloseTheWindow(theWindow);
  284.             break;
  285.         case inZoomIn:
  286.         case inZoomOut:
  287.             if (TrackBox(theWindow,mPoint,mClick))
  288.                 ZoomTheWindow(theWindow,mClick);
  289.             break;
  290.         default:
  291.             break;
  292.     }
  293. }
  294.  
  295.  
  296. ProcessKey(EventRecord *theEvent){
  297.     /* gets character typed. If menu command, calls user menu selection function */
  298.     char    theKey;
  299.     long    mSelect;
  300.     
  301.     theKey = LoWord(theEvent->message) & charCodeMask;
  302.     if ((theEvent->modifiers) & cmdKey) {
  303.         mSelect = MenuKey(theKey);
  304.         if (HiWord(mSelect) != 0)
  305.             DispatchMenu(mSelect);
  306.         HiliteMenu(0);
  307.     }
  308.     /* add code to use the key event as required */
  309. }
  310.  
  311.  
  312. ProcessAutoKey(EventRecord *theEvent){
  313.     char    theKey;
  314.     
  315.     theKey = LoWord(theEvent->message) & charCodeMask;
  316.     /* add code to handle the autokey event as required */
  317. }
  318.  
  319.  
  320. ProcessActivate(EventRecord *theEvent){
  321.     /* resolves activation type and calls appropriate user functions */
  322.     
  323.     WindowPtr    theWindow;
  324.     int        actState;
  325.     
  326.     theWindow = (WindowPtr)theEvent->message;
  327.     actState = theEvent->modifiers & activeFlag;
  328.     if (actState)
  329.         ActivateTheWindow(theWindow);
  330.     else
  331.         DeactivateTheWindow(theWindow);
  332. }
  333.  
  334.  
  335. ProcessUpdate(EventRecord *theEvent)
  336. {
  337.     /* resolves target for update, sets the port to this, calls user function */
  338.     
  339.     WindowPtr    theWindow;
  340.     GrafPtr        savePort;
  341.     
  342.     theWindow = (WindowPtr)theEvent->message;
  343.     if (theWindow != NIL) {
  344.         
  345.         GetPort(&savePort);
  346.         SetPort(theWindow);
  347.         BeginUpdate(theWindow);
  348.         DrawTheWindow(theWindow);
  349.         EndUpdate(theWindow);
  350.         SetPort(savePort);
  351.     }
  352. }
  353.  
  354.  
  355. ProcessOSEvt(EventRecord *theEvent){
  356.     /* does suspend/resume event if enabled for this application (it should be) */
  357.     
  358.     int        srState;
  359.     
  360.     if (HiWord(theEvent->message) & 0x0100) {
  361.         srState = theEvent->message & 1;
  362.         
  363.         if (srState)
  364.             ResumeApplication();
  365.         else
  366.             SuspendApplication();
  367.     }
  368. }
  369.  
  370.  
  371. ProcessHLE(EventRecord *theEvent){
  372.     /* processes Apple Events registered at Init time- for generic shell, only the
  373.         required four kinds are set up, and most are dummy code shells */
  374.         
  375.     OSErr        theErr;
  376.     
  377.     theErr = AEProcessAppleEvent(theEvent);
  378.     if (theErr != noErr)
  379.         SysBeep(1);
  380. }
  381.  
  382.  
  383. AdjustCursor(Point where,RgnHandle cursRgn)
  384. {
  385.     InitCursor();
  386. }
  387.  
  388.  
  389. CleanUp(void)
  390. {
  391.  
  392.  
  393. }